Event Queue 就是事件佇列,一次只能執行一件事,好比是買口罩排隊的概念,誰先排就誰先拿,先進先出的概念。
等待條件觸發在 JavaScript 稱為 Event queue。像是 setTimeout, addEventListener, XMLHttpRequest 等等,這些方法在執行時會先將事件放到這地方,並將所有的事件堆疊完成後,才會開始讓 event queue 內的事件被觸發。
JavaScript 是 Single Thread,啟動JavaScript語法時只會啟動一顆CPU單核,一次只能做一件事。
讓 JavaScript 感覺好像可以同時做很多事情,其實沒有,只是利用 event queue 產生時間差。
setTimeout , AJAX , Promise 等等是屬於 WebAPIs,不在 JavaScript 單線程限制範圍內。
console.log("a"); //1.先執行 a
function run(){ // run 的函數
console.log("b");
}
run(); //2.執行 run 的函數得到 b
console.log("c"); //3.最後執行 c
//---------------------------------打上以上語法,會依照單一線程陸續出現以下順序
a
b
c
console.log("a"); //1.先執行 a
function run(){ // run 的函數
console.log("b");
}
setTimeout(run,3000) //2.使用計時器會放入Event Queue,過3秒後執行 run 的函數得到 b
console.log("c"); //3.執行 c 完後,再去執行已經放進Event Queue的 b (一次只能執行一件事)
//---------------------------------打上以上語法,出現以下順序,
a
c
undefined //等待計時器
b //過3秒後出現b
console.log("a"); //1.先執行 a
function run(){ // run 的函數
console.log("b");
}
setTimeout(run,3000) //2.將計時器放入第一個event queue,3秒後執行 run 的函數得到 b
var start = Date.now();
while(Date.now() - start <= 5000){ //3.將迴圈放入第二個event queue,執行 5 秒鐘
}
console.log("c"); //4.執行 c ,
//---------------------------------打上以上語法,出現以下順序,
a
c //與b同時出現
undefined //等待計時器
b //與c同時出現
c、b 會同時出現,是因為跑放入第一個queue的計時器b,3秒後執行run函數得到b,b在queue裡待著,
然後再執行第二個queue的迴圈,5秒鐘後,queue裡沒有其他要做的,就把b放出來,就會同步跟c出現。
AJAX原名為 Asynchronous JavaScript and XML,其中XML
,是早期比較流行的資料交換格式,
現在是流行JSON
格式。
利用測試的API,得到連結套回程式碼中
利用瀏覽器 Console ,輸入程式碼
console.log("start");
var xhr = new XMLHttpRequest();
xhr.addEventListener('load',function(){
console.log(this.responseText);
});
xhr.open('GET','測試API產生出來的網址',true); //true啟動非同步
xhr.send();
console.log("end");
-----------------------------------輸入後會得到以下非同步結果
start
end
undefined
message;info
依序處理console,碰到要請求回應的就在背景處理,讓程式碼繼續往下跑,
所以會先出來 start
再來跳過請求處理,出來 end
,最後等待讀取完畢出現 message;info
console.log("start");
var xhr = new XMLHttpRequest();
xhr.open('GET','測試API產生出來的網址',false); //同步
xhr.send();
console.log(xhr.responseText);
console.log("end");
-----------------------------------輸入後會得到以下結果
start
message;info
end
同步會先 start
,再來等待中間那段請求產生的文字message;info
, end
會最後才出現。
建議盡可能都使用非同步處理,因為使用同步可能會等待很多時間處理,可能會影響渲染網頁畫面不完全,而有不好使用體驗。
如果要傳送資料給遠端,將GET
改成POST
,如果要帶參數傳回去可用FormData()
方式處理
console.log("start");
var data = new FormData(); //使用參數資料
data.append('id','5'); //寫入參數
var xhr = new XMLHttpRequest();
xhr.addEventListener('load',function(){
console.log(this.responseText);
});
xhr.open('POST','測試API產生出來的網址',true); //非同步
xhr.send(data); //帶入data參數資料
console.log("end");
console.log("start");
var data = new FormData(); //使用參數資料
data.append('id','5'); //寫入參數
var xhr = new XMLHttpRequest();
xhr.open('GET','測試API產生出來的網址',false); //同步
xhr.send(data); //帶入data參數資料
console.log(xhr.responseText);
console.log("end");
fetch("測試API產生出來的網址").then(response => {
return response.json();
}).then(data => {
console.log(data)
})
var data = new FormData();
data.append('id','5');
fetch("測試API產生出來的網址",{
method:'POST',
body: data
}).then(response => {
return response.json();
}).then(data => {
console.log(data)
})